package com.sfddata.musicpillow.oauth.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sfddata.musicpillow.common.constant.BizCodeEnum;
import com.sfddata.musicpillow.common.respose.BaseRespose;
import com.sfddata.musicpillow.common.respose.EmptyObj;
import com.sfddata.musicpillow.oauth.feign.OauthFeignService;
import com.sfddata.musicpillow.oauth.feign.UserFeignService;
import com.sfddata.musicpillow.oauth.utils.JwtUtil;
import com.sfddata.musicpillow.oauth.vo.CheckPassWord;
import com.sfddata.musicpillow.oauth.entity.UserInfoEntity;
import com.sfddata.musicpillow.oauth.feign.ThirdPartyFeignService;
import com.sfddata.musicpillow.oauth.respose.TokenResponse;
import com.sfddata.musicpillow.oauth.service.UserInfoService;
import com.sfddata.musicpillow.oauth.vo.CheckVerificationCode;
import com.sfddata.musicpillow.oauth.utils.VerCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.*;


import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("oauth")
public class OauthController {

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    UserInfoService userInfoService;
    @Autowired
    ThirdPartyFeignService thirdPartyFeignService;
    @Autowired
    UserFeignService userFeignService;
    @Autowired
    OauthFeignService oauthFeignService;
    @Value("${auth.clientId}")
    String clientId;
    @Value("${auth.clientSecret}")
    String clientSecret;
    @Value("${auth.grantType}")
    String grantType;

    String salt = "sfd";

    // 获取验证码
    @GetMapping("/getVerCode")
    public BaseRespose<EmptyObj> getVerCode(@RequestParam String phone) throws Exception {

        BaseRespose<EmptyObj> respose = thirdPartyFeignService.sendMSGByFeign(phone);
        return respose;
    }

    // 校验验证码
    @PostMapping("/checkVerCode")
    public BaseRespose<EmptyObj> checkVerCode(@RequestBody CheckVerificationCode checkCode){

        BaseRespose<EmptyObj> respose = new BaseRespose<>();
        // 验证码为空 返回异常
        if (checkCode == null){
            respose.setCode(BizCodeEnum.NOTCODE_ERROR.getCode());
            respose.setMsg(BizCodeEnum.NOTCODE_ERROR.getMsg());
            return respose;
        }
        String phoneCheck = checkCode.getPhone();
        // String code = (String) redisTemplate.opsForValue().get(phoneCheck);
        String code = checkCode.getVerification_code();
        // redis种没有get到验证码 返回验证码
        if (code == null){
            return new BaseRespose<EmptyObj>()
                    .error(BizCodeEnum.CHECKCODE_ERROR.getCode(), BizCodeEnum.CHECKCODE_ERROR.getMsg());
        }
        // 验证码验证
        Boolean tag = thirdPartyFeignService.checkCode(phoneCheck, code);
        if (tag){
            return new BaseRespose<EmptyObj>()
                    .error(BizCodeEnum.SUCCESS.getCode(), BizCodeEnum.SUCCESS.getMsg());
        }else{
            return new BaseRespose<EmptyObj>()
                    .error(BizCodeEnum.CHECKCODE_ERROR.getCode(), BizCodeEnum.CHECKCODE_ERROR.getMsg());
        }
    }

    // 验证码登录
    @PostMapping("/verCodeLogin")
    public BaseRespose<VerCode> verCodeLogin(@RequestBody CheckVerificationCode checkCode){

        BaseRespose<VerCode> respose = new BaseRespose<>();
        UserInfoEntity isRegister;
        VerCode verCode = new VerCode();
        // 验证码为空 返回异常
        if (checkCode == null){
            respose.setCode(BizCodeEnum.NOTCODE_ERROR.getCode());
            respose.setMsg(BizCodeEnum.NOTCODE_ERROR.getMsg());
            return respose;
        }


        String phoneCheck = checkCode.getPhone();
        BaseRespose<UserInfoEntity> userInfoByPhone = userFeignService.getUserInfoByPhone(phoneCheck);
        Integer id = userInfoByPhone.getData().getId();
        // String code = (String) redisTemplate.opsForValue().get(phoneCheck);
        String code = checkCode.getVerification_code();
        // redis种没有get到验证码 返回验证码
        if (code == null){
            return new BaseRespose<VerCode>()
                    .error(BizCodeEnum.CHECKCODE_ERROR.getCode(), BizCodeEnum.CHECKCODE_ERROR.getMsg());
        }
        // 验证码验证正确，先检查是不是新用户然后处理token，失败返回对应错误
        Boolean tag = thirdPartyFeignService.checkCode(phoneCheck, code);
        // String token;
        if (tag){
            // 调用oauth2的生成token方法
            // token = BCrypt.hashpw(phoneCheck, salt);
            isRegister = userInfoService.insertIfDontExist(phoneCheck);
            // 返回是否是新用户 新用户返回的User只有account
        }else{
            return new BaseRespose<VerCode>()
                    .error(BizCodeEnum.CHECKCODE_ERROR.getCode(), BizCodeEnum.CHECKCODE_ERROR.getMsg());
        }

        // 包装verCode类
        verCode.setPhone(phoneCheck);
        // 生产token, 放入redis
        String token = JwtUtil.createJWT(isRegister.getUserAccount(), "token", null);
        redisTemplate.opsForValue().set(id.toString(), token, 60*60*24*15, TimeUnit.SECONDS);


        if (isRegister.getGender() == null || isRegister.getGender() == 0){
            // 性别如果是2，他就是新用户
            verCode.set_register(false);
        }else {
            verCode.set_register(true);
        }
        verCode.setToken(token);
        verCode.setUser(isRegister);

        log.info("用户"+ checkCode.getPhone() +"验证码登录，is_register字段是" + verCode.is_register);
        respose.setData(verCode);
        respose.setCode(BizCodeEnum.SUCCESS.getCode());
        return respose;
    }

    // 弃用
    @GetMapping("/refreshToken")
    public BaseRespose<TokenResponse> refreshToken(@RequestParam String token){

        BaseRespose<TokenResponse> respose = new BaseRespose<>();
        TokenResponse tokenResponse = new TokenResponse();

        String phone_AI = (String) redisTemplate.opsForValue().get(token);
        String salt = BCrypt.gensalt();
        if (phone_AI == null){
            respose.setMsg("token错误,或者已经超时");
            respose.setCode(20001);
            return respose;
        }
        String refreshToken = BCrypt.hashpw(phone_AI, salt);
        redisTemplate.opsForValue().set(refreshToken, phone_AI, 86400, TimeUnit.SECONDS);

        tokenResponse.setToken(refreshToken);
        respose.setData(tokenResponse);
        respose.setCode(10000);
        return respose;
    }


    @GetMapping("/getUserInfo")
    public BaseRespose<UserInfoEntity> getUserInfo(@RequestParam String userAccount){

        UserInfoEntity userInfo = userInfoService.getByAccount(userAccount);
        BaseRespose<UserInfoEntity> respose = new BaseRespose<>();
        respose.setData(userInfo);
        respose.setCode(10000);
        return respose;
    }

    // 设置密码
    @PostMapping("/forgetPassword")
    public BaseRespose<UserInfoEntity> updateUserInfo(@RequestBody() UserInfoEntity userInfoVo){

        BaseRespose<UserInfoEntity> FeignRespose = userFeignService.updateUserInfo(userInfoVo);
        return FeignRespose;
    }

    // 修改头像
    @PostMapping("/modifyUserInfo")
    public void updateUserInfoByFeign(@RequestParam("phone")String phone, @RequestParam("url")String url){
        QueryWrapper<UserInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", phone);
        UserInfoEntity user = new UserInfoEntity();
        user.setHeadPortraitUrl(url);
        user.setHeadPortraitTime(new Date());
        userInfoService.update(user, queryWrapper);
        log.info("用户" + phone + "的头像更新完成，地址是" + url );
    }

    // 密码登陆
    @PostMapping("/loginPassWord")
    public BaseRespose<VerCode> loginVerCode(@RequestBody CheckPassWord checkPassWord){

        BaseRespose<VerCode> res = new BaseRespose<>();

        // 远程调用user服务
        BaseRespose<UserInfoEntity> respose = userFeignService.checkPassword(checkPassWord);
        if (respose.getCode() != 66666){
            BeanUtils.copyProperties(respose, res);
            return res;
        }
        UserInfoEntity userData = respose.getData();
        String phone = userData.getUserAccount();
        // 封装vercode
        VerCode verCode = new VerCode();
        verCode.setUser(userData);

        Integer id = userData.getId();
        Long redisV;
        String token = JwtUtil.createJWT(phone, "token", null);
        //AuthToken token = oauthFeignService.getToken(checkPassWord.getPhone(), checkPassWord.getPassword(), clientId, clientSecret, grantType);
        redisTemplate.opsForValue().set(id.toString(), token, 60*60*24*15, TimeUnit.SECONDS);

        verCode.setToken(token);
        verCode.setPhone(phone);
        if (userData.getGender() == 0){
            // 性别如果是2，他就是新用户
            verCode.set_register(false);
        }else {
            verCode.set_register(true);
        }

        BeanUtils.copyProperties(respose, res);
        res.setData(verCode);
        return res;
    }

    // 一键登陆
    @PostMapping("/loginClick")
    public BaseRespose<VerCode> loginClick(@RequestBody String loginToken){

        BaseRespose<VerCode> res = new BaseRespose<>();

        // 根据token用极光的服务获取手机号
        BaseRespose<String> numberRes = thirdPartyFeignService.getNumber(loginToken);
        if (numberRes.getCode() != 66666){
            BeanUtils.copyProperties(numberRes, res);
            return res;
        }
        String phoneNumber = numberRes.getData();

        // 根据手机号获取用户信息，如果是新用户 会生产一个新的插入表内
        BaseRespose<UserInfoEntity> userInfoRes = userFeignService.getUserInfoByPhone(phoneNumber);
        if (userInfoRes.getCode() != 66666){
            BeanUtils.copyProperties(userInfoRes, res);
            return res;
        }

        UserInfoEntity userData = userInfoRes.getData();
        Integer id = userData.getId();
        String phone = userData.getUserAccount();
        // 封装vercode
        VerCode verCode = new VerCode();
        verCode.setUser(userData);


        String token = JwtUtil.createJWT(phone, "token", null);
        //AuthToken token = oauthFeignService.getToken(checkPassWord.getPhone(), checkPassWord.getPassword(), clientId, clientSecret, grantType);
        redisTemplate.opsForValue().set(id.toString(), token, 60*60*24*15, TimeUnit.SECONDS);

        verCode.setToken(token);
        verCode.setPhone(phone);
        if ( userData.getGender() == null || userData.getGender() == 0 ){
            // 性别如果是2，他就是新用户
            verCode.set_register(false);
        }else {
            verCode.set_register(true);
        }

        log.info("用户"+ userData.getUserAccount() +"一键登录，is_register字段是" + verCode.is_register);
        System.out.println(verCode.is_register);
        System.out.println(userData.getGender());
        BeanUtils.copyProperties(userInfoRes, res);
        res.setData(verCode);
        return res;
    }
}
